﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PPI.Client.Logic;
using PPI.Client.Logic.Delegate;
using PPI.Client.Logic.Inspection;
using PPI.Client.Logic.Upload;
using PPI.Client.Logic.XML;
using PPI.Entities.Distribution;
using PPI.Entities.Enumerator;
using PPI.Entities.XML;

namespace PPI.Client.Presenter
{
    public interface IUploadMobileDatabase
    {
        int ProgressBarValue { set; }
        int ProgressBarValueImages { set; }
        event EventHandler<EventArgs> StartUpload;
        event EventHandler<EventArgs> StopUpload;
        Stack<EXmlOutboxBase> SelectedOutboxesToUpload { get; }
        bool StartStatus { set; }
        bool StopStatus { set; }

        Int32 AmountData { set; }
        Int32 AmountImage { set; }
        string CompletedUploadedData { set; }
        string CompletedUploadedImage { set; }
        string PathImage { set; }
        string PathData { set; }
        string MessageError { set; }

        void reloadOutbox();

        void ShowAlertCompleted();
    }

    public class UploadMobileDatabasePresenter
    {
        private IUploadMobileDatabase m_View;
        private LUpload m_ServiceUploadData;
        private LUpload m_ServiceUploadImages;
        private UpdateBar m_UpdateDataBarDelegate;
        private UpdateBar m_UpdateImageBarDelegate;

        private Stack<EXmlOutboxBase> m_UploadImagesStack;
        private EXmlOutboxBase m_CurrentUploadData;


        public UploadMobileDatabasePresenter(IUploadMobileDatabase view)
        {
            m_View = view;
            Initialize();
        }

        private void Initialize()
        {
            m_View.StartUpload += m_View_StartUpload;
            m_View.StopUpload += m_View_StopUpload;

            m_UpdateDataBarDelegate = UpdateProgressData;
            m_UpdateImageBarDelegate = UpdateProgressImage;

            m_ServiceUploadData = new LUpload(m_UpdateDataBarDelegate);
            m_ServiceUploadData.FinishedUpload += m_ServiceUploadData_FinishedUpload;
            m_ServiceUploadData.UploadCancel += m_ServiceUploadData_UploadCancel;
            m_ServiceUploadData.UploadError += m_ServiceUploadData_UploadError;

            m_ServiceUploadImages = new LUpload(m_UpdateImageBarDelegate);
            m_ServiceUploadImages.FinishedUpload += m_ServiceUploadImages_FinishedUpload;
            m_ServiceUploadImages.UploadCancel += m_ServiceUploadImages_UploadCancel;
            m_ServiceUploadImages.UploadError += m_ServiceUploadImages_UploadError;

            m_UploadImagesStack = new Stack<EXmlOutboxBase>();
        }

        #region Events

        #region View
        void m_View_StopUpload(object sender, EventArgs e)
        {
            Stop();
        }

        void m_View_StartUpload(object sender, EventArgs e)
        {
            
            UploadData();
        }

        #endregion

        #region ServiceData

        void m_ServiceUploadData_UploadError(object sender, UploadErrorEventArgs e)
        {
            m_View.MessageError = e.ErrorMessage;
            UploadData();
            UpdateButtonStatus();
        }

        void m_ServiceUploadData_UploadCancel(object sender, EventArgs e)
        {
            UpdateButtonStatus();
        }

        void m_ServiceUploadData_FinishedUpload(object sender, EventArgs e)
        {

            m_UploadImagesStack.Push(m_CurrentUploadData);

            UploadData();

            UploadImages();

            UpdateButtonStatus();


        }

        #endregion

        #region ServiceImage

        void m_ServiceUploadImages_UploadError(object sender, UploadErrorEventArgs e)
        {
            UpdateButtonStatus();
        }

        void m_ServiceUploadImages_UploadCancel(object sender, EventArgs e)
        {
            UpdateButtonStatus();
        }

        void m_ServiceUploadImages_FinishedUpload(object sender, EventArgs e)
        {
            UploadImages();
            UpdateButtonStatus();
            m_View.ShowAlertCompleted();
            m_View.reloadOutbox();
        }


        #endregion

        #endregion


        private void UpdateProgressData(int percentage)
        {
            m_View.ProgressBarValue = percentage;
        }

        private void UpdateProgressImage(int percentage)
        {
            m_View.ProgressBarValueImages = percentage;
        }

        private void UploadData()
        {
            if (m_View.SelectedOutboxesToUpload != null && m_View.SelectedOutboxesToUpload.Count > 0)
            {
                if (!m_ServiceUploadData.IsWorking())
                {
                    m_CurrentUploadData = m_View.SelectedOutboxesToUpload.Pop();
                    ShowDataInformation(m_CurrentUploadData);
                    if (!m_CurrentUploadData.IsDataUploaded)
                    {
                        m_ServiceUploadData.StrategyToUpload = GetStrategyToUploadData(m_CurrentUploadData);
                        m_ServiceUploadData.Start();
                    }
                    else
                    {
                        m_ServiceUploadData_FinishedUpload(this, new EventArgs());
                    }
                }
            }
            UpdateButtonStatus();
        }

        private void UploadImages()
        {
            EXmlOutboxBase Imagedatabase;
            if (!m_ServiceUploadImages.IsWorking())
            {
                
                if(m_UploadImagesStack.Count > 0)
                {
                    Imagedatabase = m_UploadImagesStack.Pop();
                    if(!Imagedatabase.IsImagesUploaded)
                    {
                        ShowImageInformation(Imagedatabase);
                        m_ServiceUploadImages.StrategyToUpload = GetStrategyToUploadImages(Imagedatabase);
                        m_ServiceUploadImages.Start();
                    }
                    else
                    {
                        m_ServiceUploadImages_FinishedUpload(this,new EventArgs());
                    }
                }
            }
            UpdateButtonStatus();
        }

        private void Stop()
        {
            if (m_ServiceUploadData.IsWorking())
            {
                m_ServiceUploadData.Stop();
            }
            if (m_ServiceUploadImages.IsWorking())
            {
                m_ServiceUploadImages.Stop();
            }
        }

        private void UpdateButtonStatus()
        {
            bool status = (!m_ServiceUploadData.IsWorking() && !m_ServiceUploadImages.IsWorking());
            m_View.StartStatus = status;
            m_View.StopStatus = !status;
        }

        public void ShowDataInformation(EXmlOutboxBase outbox)
        {
            LXmlOutbox _serviceOutbox = new LXmlOutbox(outbox);
            outbox = _serviceOutbox.GetOutboxById(outbox.Id);

            try
            {
                switch (outbox.DatabaseType)
                {
                    case DatabaseTypes.GPS:
                        m_View.AmountData = LVendor_Visit_XMissionStructure.CountMobileVisit(outbox.ConnectionString);
                        break;
                    case DatabaseTypes.Inspection:
                        m_View.AmountData = LInspectionResult.CountMobileInspectionsResults(outbox.ConnectionString);
                        break;
                }
                m_View.CompletedUploadedData = outbox.IsDataUploaded.ToString();
                m_View.PathData = outbox.ConnectionString;
            }
            catch (Exception ex)
            {
                m_View.CompletedUploadedData = "";
                m_View.PathData = "";
            }

        }

        public void ShowImageInformation(EXmlOutboxBase outbox)
        {
            LXmlOutbox _serviceOutbox = new LXmlOutbox(outbox);
            outbox = _serviceOutbox.GetOutboxById(outbox.Id);
            try
            {
                switch (outbox.DatabaseType)
                {
                    case DatabaseTypes.GPS:
                        m_View.AmountImage = LVendor_Visit_XMissionStructures_Image.CountMobileImages(outbox.ConnectionString);
                        break;
                    case DatabaseTypes.Inspection:
                        m_View.AmountImage = LInspectionImage.CountMobileImages(outbox.ConnectionString);
                        break;
                }
                m_View.CompletedUploadedImage = outbox.IsImagesUploaded.ToString();
                m_View.PathImage = outbox.ConnectionString;
            }
            catch (Exception ex)
            {
                m_View.CompletedUploadedImage = "";
                m_View.PathImage = "";
               
            }
        }

        private LUploadStrategyBase GetStrategyToUploadData(EXmlOutboxBase outbox)
        {
            LUploadStrategyBase _returnStrategy = null;
            switch (outbox.DatabaseType)
            {
                case DatabaseTypes.GPS:
                    _returnStrategy = new LUploadStrategyGPSData(outbox);
                    break;
                case DatabaseTypes.Inspection:
                    _returnStrategy = new LUploadStrategyInspection(outbox);
                    break;
                case DatabaseTypes.DistributionGPS:
                    _returnStrategy = new LUploadStrategyDistribution(DistributionType.GPS, outbox);
                    break;
                case DatabaseTypes.DistributionInspection:
                    _returnStrategy = new LUploadStrategyDistribution(DistributionType.Inspection, outbox);
                    break;
            }
            return _returnStrategy;
        }

        private LUploadStrategyBase GetStrategyToUploadImages(EXmlOutboxBase outbox)
        {
            LUploadStrategyBase _returnStrategy = null;
            switch (outbox.DatabaseType)
            {
                case DatabaseTypes.GPS:
                    _returnStrategy = new LUploadStrategyGPSImages(outbox);
                    break;
                case DatabaseTypes.Inspection:
                    _returnStrategy = new LUploadStrategyInspectionImages(outbox);
                    break;
                case DatabaseTypes.DistributionGPS:
                    _returnStrategy = new LUploadStrategyDistributionImages(outbox);
                    break;
                case DatabaseTypes.DistributionInspection:
                    _returnStrategy = new LUploadStrategyDistributionImages(outbox);
                    break;
            }

            return _returnStrategy;
        }


    }
}
